package org.custom.spring.boot.security.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.custom.spring.boot.security.interfaces.AuthenToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.validation.constraints.NotBlank;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import static org.cleaver.basic.constant.CleaverConstant.EMPTY;
import static org.custom.spring.boot.security.constant.SecurityConstant.ANONYMOUS;

/**
 * 系统优化实体类
 *
 * @author LiKun
 * @date 2021/11/8 18:50
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@TableName("system_user")
@ApiModel("系统用户实体类")
public class SystemUser implements UserDetails, AuthenToken {
    @TableId
    @ApiModelProperty(value = "id", notes = "账号ID")
    private String id;

    @ApiModelProperty(value = "enabled", notes = "账号是否可用")
    private boolean enabled;

    @NotBlank(message = "账号名称不能为空")
    @ApiModelProperty(value = "username", notes = "用户账号名称")
    private String username;

    @JsonIgnore
    @NotBlank(message = "账号密码不能为空")
    @ApiModelProperty(value = "password", notes = "用户账号密码")
    private String password;

    @TableField(exist = false)
    @ApiModelProperty(value = "systemRoles", notes = "用户权限信息")
    private Collection<SystemRole> authorities;

    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd kk:mm:ss", timezone = "GMT+8")
    @ApiModelProperty(value = "loginTime", notes = "用户登陆时间")
    private Date loginTime;

    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd kk:mm:ss", timezone = "GMT+8")
    @ApiModelProperty(value = "lastAccess", notes = "用户上次请求")
    private Date lastAccess;

    @TableField(exist = false)
    @ApiModelProperty(value = "remoteAddress", notes = "用户请求IP地址")
    private String remoteAddress;

    @TableField(exist = false)
    @ApiModelProperty(value = "lastAccessPath", notes = "用户上次请求路径")
    private String lastAccessPath;

    /**
     * 获取匿名用户数据
     *
     * @return 匿名用户
     */
    public static SystemUser getAnonymous() {
        List<SystemRole> systemRoles = Collections.singletonList(SystemRole.getAnonymous());
        return SystemUser.builder().id(EMPTY).username(ANONYMOUS).authorities(systemRoles).build();
    }

    @Override
    public String getPassword() {
        return this.password;
    }

    @Override
    public String getUsername() {
        return this.username;
    }

    @Override
    public boolean isEnabled() {
        return this.enabled;
    }

    @Override
    @JsonIgnore
    public boolean isAccountNonExpired() {
        return this.enabled;
    }

    @Override
    @JsonIgnore
    public boolean isAccountNonLocked() {
        return this.enabled;
    }

    @Override
    @JsonIgnore
    public boolean isCredentialsNonExpired() {
        return this.enabled;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.authorities;
    }

    @Override
    @JsonIgnore
    public Authentication getAuthentication() {
        return new UsernamePasswordAuthenticationToken(id, EMPTY, authorities);
    }

    /**
     * 生成用户 DTO 相关数据
     *
     * @return DTO数据
     */
    public SystemUserInfo getSystemUserInfo(String tokenKey) {
        return SystemUserInfo.builder().id(id).tokenKey(tokenKey).authorities(authorities).build();
    }
}
